home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / g__~1 / gplibs20.zoo / procbuf.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-13  |  3.3 KB  |  137 lines

  1. //    This is part of the iostream library, providing input/output for C++.
  2. //    Copyright (C) 1992 Per Bothner.
  3. //
  4. //    This library is free software; you can redistribute it and/or
  5. //    modify it under the terms of the GNU Library General Public
  6. //    License as published by the Free Software Foundation; either
  7. //    version 2 of the License, or (at your option) any later version.
  8. //
  9. //    This library is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. //    Library General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU Library General Public
  15. //    License along with this library; if not, write to the Free
  16. //    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #define _POSIX_SOURCE
  19. #include <ioprivat.h>
  20. #include <procbuf.h>
  21. #include <signal.h>
  22. #include <unistd.h>
  23. #include <sys/wait.h>
  24.  
  25.  
  26. #ifndef FORK
  27. #define FORK vfork
  28. extern "C" _G_pid_t vfork(void);
  29. #endif
  30.  
  31. procbuf::procbuf(const char *command, int mode) : filebuf()
  32. {
  33.     open(command, mode);
  34. }
  35.  
  36. #ifdef atarist
  37. extern "C" int __mint;
  38. #endif
  39.  
  40. procbuf *procbuf::open(const char *command, int mode)
  41. {
  42. #ifdef atarist
  43.     if(!__mint) return NULL;
  44. #endif
  45.     int read_or_write;
  46.     if (is_open())
  47.     return NULL;
  48.     int pipe_fds[2];
  49.     int parent_end, child_end;
  50.     if (::pipe(pipe_fds) < 0)
  51.     return NULL;
  52.     if (mode == ios::in) {
  53.     parent_end = pipe_fds[0];
  54.     child_end = pipe_fds[1];
  55.     read_or_write = _S_NO_WRITES;
  56.     }
  57.     else {
  58.     parent_end = pipe_fds[1];
  59.     child_end = pipe_fds[0];
  60.     read_or_write = _S_NO_READS;
  61.     }
  62.     _pid = FORK();
  63.     if (_pid == 0) {
  64.     ::close(parent_end);
  65.     int child_std_end = mode == ios::in ? 1 : 0;
  66.     if (child_end != child_std_end) {
  67.         ::dup2(child_end, child_std_end);
  68.         ::close(child_end);
  69.     }
  70. #ifdef atarist
  71.     ::execvp(command, NULL);
  72. #else
  73.     ::execl("/bin/sh", "sh", "-c", command, NULL);
  74. #endif
  75.     ::_exit(127);
  76.     }
  77.     ::close(child_end);
  78.     if (_pid < 0) {
  79.     ::close(parent_end);
  80.     return NULL;
  81.     }
  82.     _fb._fileno = parent_end;
  83.     xsetflags(read_or_write, _S_NO_READS|_S_NO_WRITES);
  84.     return this;
  85. }
  86.  
  87. /* #define USE_SIGMASK */
  88.  
  89. int procbuf::sys_close()
  90. {
  91.     _G_pid_t wait_pid;
  92. #ifdef atarist
  93.     if(!__mint) return -1;
  94. #endif
  95.     int status = filebuf::sys_close();
  96.     if (status < 0)
  97.     return status;
  98.     int wstatus;
  99. #if defined(SIG_BLOCK) && defined(SIG_SETMASK)
  100.     sigset_t set, oset;
  101.     sigemptyset (&set);
  102.     sigaddset (&set, SIGINT);
  103.     sigaddset (&set, SIGQUIT);
  104.     sigaddset (&set, SIGHUP);
  105.     sigprocmask (SIG_BLOCK, &set, &oset);
  106. #else
  107. #ifdef USE_SIGMASK
  108.     int mask = sigblock(sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGHUP));
  109. #else
  110.     typedef void (*void_func)(int);
  111.     void_func intsave = (void_func)signal(SIGINT, SIG_IGN);
  112.     void_func quitsave = (void_func)signal(SIGQUIT, SIG_IGN);
  113.     void_func hupsave = (void_func)signal(SIGHUP, SIG_IGN);
  114. #endif
  115. #endif
  116.     while ((wait_pid = wait(&wstatus)) != _pid && wait_pid != -1) { }
  117. #if defined(SIG_BLOCK) && defined(SIG_SETMASK)
  118.     sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
  119. #else
  120. #ifdef USE_SIGMASK
  121.     (void) sigsetmask(mask);
  122. #else
  123.     signal(SIGINT, intsave);
  124.     signal(SIGQUIT, quitsave);
  125.     signal(SIGHUP, hupsave);
  126. #endif
  127. #endif
  128.     if (wait_pid == -1)
  129.     return -1;
  130.     return 0;
  131. }
  132.  
  133. procbuf::~procbuf()
  134. {
  135.     close();
  136. }
  137.